
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Database instrumentation &#8212; Django 2.2.12.dev20200304094918 documentation</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/language_data.js"></script>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="next" title="Examples of model relationship API usage" href="examples/index.html" />
    <link rel="prev" title="Database access optimization" href="optimization.html" />



 
<script type="text/javascript" src="../../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django 2.2.12.dev20200304094918 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="optimization.html" title="Database access optimization">previous</a>
     |
    <a href="../index.html" title="Using Django" accesskey="U">up</a>
   |
    <a href="examples/index.html" title="Examples of model relationship API usage">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="topics-db-instrumentation">
            
  <div class="section" id="s-database-instrumentation">
<span id="database-instrumentation"></span><h1>Database instrumentation<a class="headerlink" href="#database-instrumentation" title="Permalink to this headline">¶</a></h1>
<p>To help you understand and control the queries issued by your code, Django
provides a hook for installing wrapper functions around the execution of
database queries. For example, wrappers can count queries, measure query
duration, log queries, or even prevent query execution (e.g. to make sure that
no queries are issued while rendering a template with prefetched data).</p>
<p>The wrappers are modeled after <a class="reference internal" href="../http/middleware.html"><span class="doc">middleware</span></a> –
they are callables which take another callable as one of their arguments. They
call that callable to invoke the (possibly wrapped) database query, and they
can do what they want around that call. They are, however, created and
installed by user code, and so don’t need a separate factory like middleware do.</p>
<p>Installing a wrapper is done in a context manager – so the wrappers are
temporary and specific to some flow in your code.</p>
<p>As mentioned above, an example of a wrapper is a query execution blocker. It
could look like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">blocker</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
    <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">&#39;No database access allowed here.&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>And it would be used in a view to block queries from the template like so:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db</span> <span class="k">import</span> <span class="n">connection</span>
<span class="kn">from</span> <span class="nn">django.shortcuts</span> <span class="k">import</span> <span class="n">render</span>

<span class="k">def</span> <span class="nf">my_view</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="o">...</span><span class="p">}</span>  <span class="c1"># Code to generate context with all data.</span>
    <span class="n">template_name</span> <span class="o">=</span> <span class="o">...</span>
    <span class="k">with</span> <span class="n">connection</span><span class="o">.</span><span class="n">execute_wrapper</span><span class="p">(</span><span class="n">blocker</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">render</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">template_name</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
</pre></div>
</div>
<p>The parameters sent to the wrappers are:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">execute</span></code> – a callable, which should be invoked with the rest of the
parameters in order to execute the query.</li>
<li><code class="docutils literal notranslate"><span class="pre">sql</span></code> – a <code class="docutils literal notranslate"><span class="pre">str</span></code>, the SQL query to be sent to the database.</li>
<li><code class="docutils literal notranslate"><span class="pre">params</span></code> – a list/tuple of parameter values for the SQL command, or a
list/tuple of lists/tuples if the wrapped call is <code class="docutils literal notranslate"><span class="pre">executemany()</span></code>.</li>
<li><code class="docutils literal notranslate"><span class="pre">many</span></code> – a <code class="docutils literal notranslate"><span class="pre">bool</span></code> indicating whether the ultimately invoked call is
<code class="docutils literal notranslate"><span class="pre">execute()</span></code> or <code class="docutils literal notranslate"><span class="pre">executemany()</span></code> (and whether <code class="docutils literal notranslate"><span class="pre">params</span></code> is expected to be
a sequence of values, or a sequence of sequences of values).</li>
<li><code class="docutils literal notranslate"><span class="pre">context</span></code> – a dictionary with further data about the context of
invocation. This includes the connection and cursor.</li>
</ul>
<p>Using the parameters, a slightly more complex version of the blocker could
include the connection name in the error message:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">blocker</span><span class="p">(</span><span class="n">execute</span><span class="p">,</span> <span class="n">sql</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">many</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
    <span class="n">alias</span> <span class="o">=</span> <span class="n">context</span><span class="p">[</span><span class="s1">&#39;connection&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span>
    <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Access to database &#39;</span><span class="si">{}</span><span class="s2">&#39; blocked here&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">alias</span><span class="p">))</span>
</pre></div>
</div>
<p>For a more complete example, a query logger could look like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">time</span>

<span class="k">class</span> <span class="nc">QueryLogger</span><span class="p">:</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">queries</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">execute</span><span class="p">,</span> <span class="n">sql</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">many</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="n">current_query</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;sql&#39;</span><span class="p">:</span> <span class="n">sql</span><span class="p">,</span> <span class="s1">&#39;params&#39;</span><span class="p">:</span> <span class="n">params</span><span class="p">,</span> <span class="s1">&#39;many&#39;</span><span class="p">:</span> <span class="n">many</span><span class="p">}</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">result</span> <span class="o">=</span> <span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">many</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
            <span class="n">current_query</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;error&#39;</span>
            <span class="n">current_query</span><span class="p">[</span><span class="s1">&#39;exception&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">e</span>
            <span class="k">raise</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">current_query</span><span class="p">[</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;ok&#39;</span>
            <span class="k">return</span> <span class="n">result</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">duration</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span>
            <span class="n">current_query</span><span class="p">[</span><span class="s1">&#39;duration&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">duration</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">queries</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_query</span><span class="p">)</span>
</pre></div>
</div>
<p>To use this, you would create a logger object and install it as a wrapper:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db</span> <span class="k">import</span> <span class="n">connection</span>

<span class="n">ql</span> <span class="o">=</span> <span class="n">QueryLogger</span><span class="p">()</span>
<span class="k">with</span> <span class="n">connection</span><span class="o">.</span><span class="n">execute_wrapper</span><span class="p">(</span><span class="n">ql</span><span class="p">):</span>
    <span class="n">do_queries</span><span class="p">()</span>
<span class="c1"># Now we can print the log.</span>
<span class="nb">print</span><span class="p">(</span><span class="n">ql</span><span class="o">.</span><span class="n">queries</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="s-connection-execute-wrapper">
<span id="connection-execute-wrapper"></span><h2><code class="docutils literal notranslate"><span class="pre">connection.execute_wrapper()</span></code><a class="headerlink" href="#connection-execute-wrapper" title="Permalink to this headline">¶</a></h2>
<dl class="method">
<dt id="django.db.backends.base.DatabaseWrapper.execute_wrapper">
<code class="descname">execute_wrapper</code>(<em>wrapper</em>)<a class="headerlink" href="#django.db.backends.base.DatabaseWrapper.execute_wrapper" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<p>Returns a context manager which, when entered, installs a wrapper around
database query executions, and when exited, removes the wrapper. The wrapper is
installed on the thread-local connection object.</p>
<p><code class="docutils literal notranslate"><span class="pre">wrapper</span></code> is a callable taking five arguments.  It is called for every query
execution in the scope of the context manager, with arguments <code class="docutils literal notranslate"><span class="pre">execute</span></code>,
<code class="docutils literal notranslate"><span class="pre">sql</span></code>, <code class="docutils literal notranslate"><span class="pre">params</span></code>, <code class="docutils literal notranslate"><span class="pre">many</span></code>, and <code class="docutils literal notranslate"><span class="pre">context</span></code> as described above. It’s
expected to call <code class="docutils literal notranslate"><span class="pre">execute(sql,</span> <span class="pre">params,</span> <span class="pre">many,</span> <span class="pre">context)</span></code> and return the return
value of that call.</p>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Database instrumentation</a><ul>
<li><a class="reference internal" href="#connection-execute-wrapper"><code class="docutils literal notranslate"><span class="pre">connection.execute_wrapper()</span></code></a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="optimization.html"
                        title="previous chapter">Database access optimization</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="examples/index.html"
                        title="next chapter">Examples of model relationship API usage</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/topics/db/instrumentation.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Mar 04, 2020</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="optimization.html" title="Database access optimization">previous</a>
     |
    <a href="../index.html" title="Using Django" accesskey="U">up</a>
   |
    <a href="examples/index.html" title="Examples of model relationship API usage">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>